package com.gitee.wsl.time.chinese.bean

import com.gitee.wsl.text.format.format
import com.gitee.wsl.time.chinese.Lunar
import com.gitee.wsl.time.chinese.util.LunarUtil
import com.gitee.wsl.time.chinese.util.TaoFestival
import com.gitee.wsl.time.chinese.util.TaoUtil
import kotlin.math.abs

/**
 * 道历
 *
 * @author 6tail
 */
class Tao(
    /**
     * 阴历
     */
    val lunar: Lunar,
) {
    val year: Int
        get() = lunar.year - BIRTH_YEAR

    val month: Int
        get() = lunar.month

    val day: Int
        get() = lunar.day

    val yearInChinese: String
        get() {
            val y = this.year.toString() + ""
            val s = StringBuilder()
            var i = 0
            val j = y.length
            while (i < j) {
                s.append(LunarUtil.NUMBER[y.get(i).code - '0'.code])
                i++
            }
            return s.toString()
        }

    val monthInChinese: String
        get() = lunar.monthInChinese

    val dayInChinese: String
        get() = lunar.dayInChinese

    val festivals: List<TaoFestival?>
        get() {
            val l= ArrayList<TaoFestival>()
            val fs = TaoUtil.FESTIVAL.get(this.month.toString() + "-" + this.day)
            if (null != fs) {
                l.addAll(fs)
            }
            val jq = lunar.getJieQi()
            if ("冬至" == jq) {
                l.add(TaoFestival("元始天尊圣诞"))
            } else if ("夏至" == jq) {
                l.add(TaoFestival("灵宝天尊圣诞"))
            }
            // 八节日
            var f = TaoUtil.BA_JIE.get(jq)
            if (null != f) {
                l.add(TaoFestival(f))
            }
            // 八会日
            f = TaoUtil.BA_HUI.get(lunar.dayInGanZhi)
            if (null != f) {
                l.add(TaoFestival(f))
            }
            return l
        }

    private fun isDayIn(days: Array<String>): Boolean {
        val md = this.month.toString() + "-" + this.day
        for (d in days) {
            if (md == d) {
                return true
            }
        }
        return false
    }

    val isDaySanHui: Boolean
        /**
         * 是否三会日
         *
         * @return true/false
         */
        get() = isDayIn(TaoUtil.SAN_HUI)

    val isDaySanYuan: Boolean
        /**
         * 是否三元日
         *
         * @return true/false
         */
        get() = isDayIn(TaoUtil.SAN_YUAN)

    val isDayBaJie: Boolean
        /**
         * 是否八节日
         *
         * @return true/false
         */
        get() = TaoUtil.BA_JIE.containsKey(lunar.getJieQi())

    val isDayWuLa: Boolean
        /**
         * 是否五腊日
         *
         * @return true/false
         */
        get() = isDayIn(TaoUtil.WU_LA)

    val isDayBaHui: Boolean
        /**
         * 是否八会日
         *
         * @return true/false
         */
        get() = TaoUtil.BA_HUI.containsKey(lunar.dayInGanZhi)

    val isDayMingWu: Boolean
        /**
         * 是否明戊日
         *
         * @return true/false
         */
        get() = "戊" == lunar.dayGan

    val isDayAnWu: Boolean
        /**
         * 是否暗戊日
         *
         * @return true/false
         */
        get() = lunar.dayZhi == TaoUtil.AN_WU[abs(this.month) - 1]

    val isDayWu: Boolean
        /**
         * 是否戊日
         *
         * @return true/false
         */
        get() = this.isDayMingWu || this.isDayAnWu

    val isDayTianShe: Boolean
        /**
         * 是否天赦日
         *
         * @return true/false
         */
        get() {
            var ret = false
            val mz = lunar.monthZhi
            val dgz = lunar.dayInGanZhi
            if ("寅卯辰".contains(mz)) {
                if ("戊寅" == dgz) {
                    ret = true
                }
            } else if ("巳午未".contains(mz)) {
                if ("甲午" == dgz) {
                    ret = true
                }
            } else if ("申酉戌".contains(mz)) {
                if ("戊申" == dgz) {
                    ret = true
                }
            } else if ("亥子丑".contains(mz)) {
                if ("甲子" == dgz) {
                    ret = true
                }
            }
            return ret
        }

    override fun toString(): String {
        return String.format("%s年%s月%s", this.yearInChinese, this.monthInChinese, this.dayInChinese)
    }

    fun toFullString(): String {
        return String.format(
            "道歷%s年，天運%s年，%s月，%s日。%s月%s日，%s時。",
            this.yearInChinese, lunar.yearInGanZhi, lunar.monthInGanZhi, lunar.dayInGanZhi,
            this.monthInChinese,
            this.dayInChinese, lunar.timeZhi
        )
    }

    companion object {
        val BIRTH_YEAR: Int = -2697

        fun fromLunar(lunar: Lunar): Tao {
            return Tao(lunar)
        }

        fun fromYmdHms(year: Int, month: Int, day: Int, hour: Int, minute: Int, second: Int): Tao {
            return fromLunar(Lunar.Companion.fromYmdHms(year + BIRTH_YEAR, month, day, hour, minute, second))
        }

        fun fromYmd(year: Int, month: Int, day: Int): Tao {
            return fromYmdHms(year, month, day, 0, 0, 0)
        }
    }
}
